using System;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using DatabaseBackup.Models;

namespace DatabaseBackup.Services
{
    /// <summary>
    /// 备份任务调度器
    /// </summary>
    public class BackupScheduler
    {
        private readonly AppConfig _config;
        private readonly IBackupService<MySqlDatabaseConfig> _mySqlBackupService;
        private readonly IBackupService<SqlServerDatabaseConfig> _sqlServerBackupService;
        private Timer _timer;

        public BackupScheduler(AppConfig config)
        {
            _config = config;
            _mySqlBackupService = new MySqlBackupService();
            _sqlServerBackupService = new SqlServerBackupService();
        }

        /// <summary>
        /// 启动调度器
        /// </summary>
        public void Start()
        {
            Console.WriteLine("备份调度器已启动...");
            Console.WriteLine($"每日备份时间: {_config.BackupHour:D2}:{_config.BackupMinute:D2}");

            // 立即计算下一次执行时间并启动定时器
            ScheduleNextBackup();
        }

        /// <summary>
        /// 计算并安排下一次备份
        /// </summary>
        private void ScheduleNextBackup()
        {
            DateTime now = DateTime.Now;
            DateTime nextRun = new DateTime(now.Year, now.Month, now.Day,
                _config.BackupHour, _config.BackupMinute, 0);

            // 如果今天的备份时间已过，则安排到明天
            if (nextRun <= now)
            {
                nextRun = nextRun.AddDays(1);
            }

            TimeSpan timeToWait = nextRun - now;
            Console.WriteLine($"下次备份将在 {nextRun:yyyy-MM-dd HH:mm:ss} 执行（{timeToWait.TotalHours:F1}小时后）");

            // 启动定时器
            _timer?.Dispose();
            _timer = new Timer(OnBackupTimerElapsed, null, timeToWait, TimeSpan.FromDays(1));
        }

        /// <summary>
        /// 定时器触发时执行备份
        /// </summary>
        private async void OnBackupTimerElapsed(object state)
        {
            Console.WriteLine($"===== 开始执行备份任务: {DateTime.Now:yyyy-MM-dd HH:mm:ss} =====");

            // 执行所有启用的数据库备份
            await PerformAllBackups();

            // 清理旧备份文件
            CleanupOldBackups();

            Console.WriteLine($"===== 备份任务执行完成: {DateTime.Now:yyyy-MM-dd HH:mm:ss} =====");
        }

        /// <summary>
        /// 执行所有启用的数据库备份
        /// </summary>
        private async Task PerformAllBackups()
        {
            // 备份MySQL数据库
            foreach (var dbConfig in _config.MySqlDatabases.Where(d => d.Enabled))
            {
                await _mySqlBackupService.BackupAsync(dbConfig, _config.BackupPath);
            }

            // 备份SQL Server数据库
            foreach (var dbConfig in _config.SqlServerDatabases.Where(d => d.Enabled))
            {
                await _sqlServerBackupService.BackupAsync(dbConfig, _config.BackupPath);
            }
        }

        /// <summary>
        /// 清理过期的备份文件
        /// </summary>
        private void CleanupOldBackups()
        {
            try
            {
                if (!Directory.Exists(_config.BackupPath))
                    return;

                DateTime retentionDate = DateTime.Now.AddDays(-_config.RetainDays);
                var files = Directory.GetFiles(_config.BackupPath);
                int deletedCount = 0;

                foreach (var file in files)
                {
                    if (File.GetLastWriteTime(file) < retentionDate)
                    {
                        File.Delete(file);
                        deletedCount++;
                    }
                }

                Console.WriteLine($"已清理 {deletedCount} 个过期备份文件");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"清理旧备份时出错: {ex.Message}");
            }
        }

        /// <summary>
        /// 停止调度器
        /// </summary>
        public void Stop()
        {
            _timer?.Dispose();
            Console.WriteLine("备份调度器已停止");
        }
    }
}
